package com.diploma.project.aiqiyi.utils;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

@Slf4j
public class FileUtil {

    /**
     * 写入文件,末尾自动添加\r\n
     * utf-8  追加
     *
     * @param path
     * @param str
     */
    public static void writeAppend(String path, String str) {
        try {
            File file = new File(path);
            if (!file.getParentFile().exists())
                file.getParentFile().mkdirs();
            if (!file.exists())
                file.createNewFile();
            fillAppend(path, str);
        } catch (IOException ex) {
            System.out.println(ex.getStackTrace());
        }
    }

    private static void fillAppend(String path, String content) {
        try (FileWriter writer = new FileWriter(path, true)) {
            writer.write(content);
            writer.write("\r\n");
        } catch (IOException e) {
            log.error(ExceptionUtils.getStackTrace(e));
        }
    }

    /**
     * 写入文件,末尾自动添加\r\n
     *
     * @param path
     * @param str
     */
    public static void write(String path, String str, boolean is_append) {
        try {
            File file = new File(path);
            if (!file.exists())
                file.createNewFile();
            FileOutputStream out = new FileOutputStream(file, is_append); //true表示追加
            StringBuffer sb = new StringBuffer();
            sb.append(str + "\r\n");
            out.write(sb.toString().getBytes("UTF-8"));
            out.close();
        } catch (IOException ex) {
            System.out.println(ex.getStackTrace());
        }
    }

    /**
     * 整个文件以string放回，添加\r\n换行
     *
     * @param path
     * @return
     */
    public static String readByString(String path) {
        StringBuffer sb = new StringBuffer();
        String tempstr = null;
        try {
            File file = new File(path);
            if (!file.exists())
                throw new FileNotFoundException();
            FileInputStream fis = new FileInputStream(file);
            BufferedReader br = new BufferedReader(new InputStreamReader(fis, "utf-8"));
            while ((tempstr = br.readLine()) != null) {
                sb.append(tempstr + "\r\n");
            }
        } catch (IOException ex) {
            System.out.println(ex.getStackTrace());
        }
        return sb.toString();
    }

    /**
     * 加入编码
     * 整个文件以string放回，添加\r\n换行
     *
     * @param path
     * @return
     */
    public static String readByStringAndEncode(String path, String encode) {
        StringBuffer sb = new StringBuffer();
        String tempstr = null;
        try {
            File file = new File(path);
            if (!file.exists())
                throw new FileNotFoundException();
            FileInputStream fis = new FileInputStream(file);
            BufferedReader br = new BufferedReader(new InputStreamReader(fis, encode));
            while ((tempstr = br.readLine()) != null) {
                sb.append(tempstr + "\r\n");
            }
        } catch (IOException ex) {
            System.out.println(ex.getStackTrace());
        }
        return sb.toString();
    }

    /**
     * 按行读取文件，以list<String>的形式返回
     *
     * @param path
     * @return
     */
    public static List<String> readByList(String path) {
        List<String> lines = new ArrayList<String>();
        String tempstr = null;
        try {
            File file = new File(path);
            if (!file.exists()) {
                throw new FileNotFoundException();
            }
            FileInputStream fis = new FileInputStream(file);
            BufferedReader br = new BufferedReader(new InputStreamReader(fis, "utf-8"));
            while ((tempstr = br.readLine()) != null) {
                lines.add(tempstr.toString());
            }
        } catch (IOException ex) {
            System.out.println(ex.getStackTrace());
        }
        return lines;
    }

    /**
     * 创建目录
     *
     * @param dir_path
     */
    public static void mkDir(String dir_path) {
        File myFolderPath = new File(dir_path);
        try {
            if (!myFolderPath.exists()) {
                myFolderPath.mkdir();
            }
        } catch (Exception e) {
            log.error("新建目录操作出错");
            log.error(ExceptionUtils.getStackTrace(e));
        }
    }

    /**
     * 创建文件
     *
     * @param file_path
     */
    public static void createNewFile(String file_path) {
        File myFilePath = new File(file_path);
        try {
            if (!myFilePath.exists()) {
                myFilePath.createNewFile();
            }
        } catch (Exception e) {
            log.error("新建文件操作出错");
            log.error(ExceptionUtils.getStackTrace(e));
        }
    }

    /**
     * 递归删除文件或者目录
     *
     * @param file_path
     */
    public static void deleteEveryThing(String file_path) {
        try {
            File file = new File(file_path);
            if (!file.exists()) {
                return;
            }
            if (file.isFile()) {
                file.delete();
            } else {
                File[] files = file.listFiles();
                for (int i = 0; i < files.length; i++) {
                    String root = files[i].getAbsolutePath();//得到子文件或文件夹的绝对路径
                    deleteEveryThing(root);
                }
                file.delete();
            }
        } catch (Exception e) {
            log.error("删除文件失败");
        }
    }

    /**
     * 得到一个文件夹下所有文件
     */
    public static List<String> getAllFileNameInFold(String fold_path) {
        List<String> file_paths = new ArrayList<String>();

        LinkedList<String> folderList = new LinkedList<String>();
        folderList.add(fold_path);
        while (folderList.size() > 0) {
            File file = new File(folderList.peekLast());
            folderList.removeLast();
            File[] files = file.listFiles();
            ArrayList<File> fileList = new ArrayList<File>();
            for (int i = 0; i < files.length; i++) {
                if (files[i].isDirectory()) {
                    folderList.add(files[i].getPath());
                } else {
                    fileList.add(files[i]);
                }
            }
            for (File f : fileList) {
                file_paths.add(f.getAbsoluteFile().getPath());
            }
        }
        return file_paths;
    }

    /**
     * 生成一个临时文件并获取其绝对路径
     *
     * @param pattern
     * @return
     */
    public static String getPatternFilePath(String pattern) {
        // 获取容器资源解析器
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            // 获取所有匹配的文件
            Resource[] resources = resolver.getResources(pattern);
            for (Resource resource : resources) {
                // 获得文件流，因为在jar文件中，不能直接通过文件资源路径拿到文件，但是可以在jar包中拿到文件流
                InputStream stream = resource.getInputStream();
                if (log.isInfoEnabled()) {
                    log.info("读取的文件流  [" + stream + "]");
                }
                String targetFilePath = System.getProperty("java.io.tmpdir") + "/" + resource.getFilename();
                if (log.isInfoEnabled()) {
                    log.info("放置位置  [" + targetFilePath + "]");
                }
                File ttfFile = new File(targetFilePath);
                FileUtils.copyInputStreamToFile(stream, ttfFile);
                return ttfFile.getAbsolutePath();
            }
        } catch (IOException e) {
            if (log.isErrorEnabled()) {
                log.error("读取文件流失败，写入本地库失败！ " + e);
            }
        }
        return null;
    }

    public static List<List<String>> parseStringToList(String content) {
        if (StringUtil.isBlank(content))
            return Lists.newArrayList();

        List<List<String>> resultList = Lists.newArrayList();
        List<String> eleList = null;
        String[] resultArr = content.split(System.getProperty("line.separator"));
        String[] eleArr = null;
        for (String ra : resultArr) {
            if (StringUtils.isEmpty(ra.trim()))
                continue;

            eleArr = ra.split("\\|");
            eleList = Lists.newArrayList();
            for (String ele : eleArr) {
                eleList.add(ele);
            }
            resultList.add(eleList);
        }
        return resultList;
    }

    /**
     * @param imgStr   base64编码字符串
     * @param filePath 图片路径-具体到文件
     * @return
     * @throws Exception
     * @Description: 将base64编码字符串转换为图片
     * @Author:
     * @CreateTime:
     */
    public static void byteToFile(String imgStr, String filePath, String fileName) throws Exception {
        if (StringUtil.isBlank(imgStr)) {
            throw new Exception("face++返回的最优图片不存在");
        }
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        try {
            FileOutputStream write = new FileOutputStream(new File(filePath + File.separator + fileName));
            byte[] decoderBytes = Base64.decodeBase64(imgStr.substring(imgStr.indexOf(",") + 1));
            log.info("二进制加密图片待解析：=====================");
            write.write(decoderBytes);
            write.close();
        } catch (Exception e) {
            log.error(LogUtils.getCommLog(e.getMessage()));
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 校验经过base64编码的字符串是否是图片文件
     *
     * @param base64Str
     * @return
     */
    public static boolean isImageFromBase64(String base64Str) {
        boolean flag = false;
        if (StringUtil.isEmpty(base64Str)) {// 图像数据为空
            return false;
        }
        try {
            BufferedImage bufImg = javax.imageio.ImageIO.read(new ByteArrayInputStream(Base64.decodeBase64(base64Str)));
            if (null == bufImg) {
                return flag;
            }
            flag = true;
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
        return flag;
    }

    /**
     * 将图片转换成base64格式进行存储
     *
     * @param imagePath
     * @return
     */
    public static String encodeToString(String imagePath, InputStream instream) throws IOException {
        String type = org.apache.commons.lang.StringUtils.substring(imagePath, imagePath.lastIndexOf(".") + 1);
        //BufferedImage image = ImageIO.read(new File(imagePath));
        BufferedImage image = ImageIO.read(instream);
        String imageString = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, type, bos);
            byte[] imageBytes = bos.toByteArray();
            imageString = Base64.encodeBase64String(imageBytes);
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imageString;
    }
}